#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "mcp_encrypt.h"

// Base64 编码表
static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Base64 解码表
static const int base64_decode_table[256] = {
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
    52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1, 0, 1, 2, 3, 4, 5, 6,
     7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
    -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
    49,50,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};

// 简单的 XOR 加密函数
unsigned char* mcp_encrypt0(const char* input, const char* key, int* output_len) {
    if (!input || !key) return NULL;
    
    int input_len = strlen(input);  // 注意：这里不包括 \0
    int key_len = strlen(key);

    if (key_len == 0) return NULL;

    unsigned char* encrypted = (unsigned char*)malloc(input_len);
    if (!encrypted) return NULL;

    for (int i = 0; i < input_len; i++) {
        encrypted[i] = input[i] ^ key[i % key_len];
    }

    if (output_len) {
        *output_len = input_len;
    }
    
    return encrypted;
}

// 简单的 XOR 解密函数
char* mcp_decrypt0(const unsigned char* input, int input_len, const char* key) {
    if (!input || !key) return NULL;

    int key_len = strlen(key);
    if (key_len == 0) return NULL;

    char* decrypted = (char*)malloc(input_len + 1);
    if (!decrypted) return NULL;

    for (int i = 0; i < input_len; i++) {
        decrypted[i] = input[i] ^ key[i % key_len];
    }
    decrypted[input_len] = '\0';

    return decrypted;
}

// Base64 解码
unsigned char* base64_decode(const char* encoded, int* output_length) {
    if (!encoded) return NULL;

    int input_length = strlen(encoded);
    if (input_length % 4 != 0) return NULL;

    // 计算输出长度
    int padding = 0;
    if (input_length > 0 && encoded[input_length - 1] == '=') padding++;
    if (input_length > 1 && encoded[input_length - 2] == '=') padding++;

    *output_length = 3 * (input_length / 4) - padding;
    unsigned char* decoded = (unsigned char*)malloc(*output_length);
    if (!decoded) return NULL;

    int i = 0, j = 0;
    uint32_t sextet_a = 0, sextet_b = 0, sextet_c = 0, sextet_d = 0;

    while (i < input_length) {
        sextet_a = encoded[i] == '=' ? 0 & i++ : base64_decode_table[(unsigned char)encoded[i++]];
        sextet_b = encoded[i] == '=' ? 0 & i++ : base64_decode_table[(unsigned char)encoded[i++]];
        sextet_c = encoded[i] == '=' ? 0 & i++ : base64_decode_table[(unsigned char)encoded[i++]];
        sextet_d = encoded[i] == '=' ? 0 & i++ : base64_decode_table[(unsigned char)encoded[i++]];

        uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d;

        if (j < *output_length) decoded[j++] = (triple >> 16) & 0xFF;
        if (j < *output_length) decoded[j++] = (triple >> 8) & 0xFF;
        if (j < *output_length) decoded[j++] = triple & 0xFF;
    }

    return decoded;
}

// 安全的解密函数（Base64解码 + 解密）
char* mcp_decrypt(const char* base64_data, const char* key) {
    if (!base64_data || !key) return NULL;

    // 1. Base64解码
    int decoded_len;
    unsigned char* decoded_data = base64_decode(base64_data, &decoded_len);
    if (!decoded_data) return NULL;

    // 2. 解密
    char* decrypted = mcp_decrypt0(decoded_data, decoded_len, key);
    free(decoded_data);

    return decrypted;
}
// 字节数组转十六进制字符串
char* bytes_to_hex(const char* data, int length) {
    if (!data || length <= 0) return NULL;

    char* hex_string = (char*)malloc(length * 2 + 1);
    if (!hex_string) return NULL;

    for (int i = 0; i < length; i++) {
        sprintf(hex_string + i * 2, "%02X", data[i]);
    }
    hex_string[length * 2] = '\0';

    return hex_string;
}

// 十六进制字符串转字节数组
unsigned char* hex_to_bytes(const char* hex_string, int* output_len) {
    if (!hex_string) return NULL;

    int hex_len = strlen(hex_string);
    if (hex_len % 2 != 0) return NULL;

    int byte_len = hex_len / 2;
    unsigned char* bytes = (unsigned char*)malloc(byte_len);
    if (!bytes) return NULL;

    for (int i = 0; i < byte_len; i++) {
        sscanf(hex_string + i * 2, "%2hhx", &bytes[i]);
    }

    if (output_len) {
        *output_len = byte_len;
    }

    return bytes;
}

/**
 * base64_encode 编码
 * @param data
 * @param length
 * @return
 */
char* base64_encode(const unsigned char* data, int length) {
    char* encoded = (char*)malloc((length + 2) / 3 * 4 + 1);
    if (!encoded) return NULL;

    int i = 0, j = 0;
    while (i < length) {
        uint32_t octet_a = i < length ? data[i++] : 0;
        uint32_t octet_b = i < length ? data[i++] : 0;
        uint32_t octet_c = i < length ? data[i++] : 0;

        uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;

        encoded[j++] = base64_chars[(triple >> 18) & 0x3F];
        encoded[j++] = base64_chars[(triple >> 12) & 0x3F];
        encoded[j++] = base64_chars[(triple >> 6) & 0x3F];
        encoded[j++] = base64_chars[triple & 0x3F];
    }

    // 添加padding
    int padding = length % 3;
    if (padding == 1) {
        encoded[j - 2] = '=';
        encoded[j - 1] = '=';
    } else if (padding == 2) {
        encoded[j - 1] = '=';
    }

    encoded[j] = '\0';
    return encoded;
}
// 使用Base64包装加密
char* mcp_encrypt(const char* input, const char* key) {
    int encrypted_len=0;
    unsigned char* encrypted = mcp_encrypt0(input, key, &encrypted_len);
    if (!encrypted) return NULL;

    char* base64_encoded = base64_encode(encrypted, encrypted_len);
    free(encrypted);

    return base64_encoded;
}

// 测试函数
void test_encryption() {
    // const char* original_json = "{\"id\": \"300281\", \"version\": \"1.0\",\"name\":\"李疯疯\"}";
    const char* original_json = "{\"device_id\":\"300281\",\"name\":\"张天风\",\"expire\":3600,\"is_camera\":false}";
    const char* key = "mcp_protocol_2025";

    printf("=== C encryption and decryption testing ===\n");
    printf("Origin JSON: %s\n", original_json);
    printf("Origin JSON len: %zu\n", strlen(original_json));
    printf("key: %s\n", key);

    // 加密
    int encrypted_len=0;
    char* encrypted = mcp_encrypt(original_json, key);
    if (encrypted) {
        char* hex_encrypted = bytes_to_hex(encrypted, strlen(encrypted));
        printf("Length after encryption: %d\n", encrypted_len);
        printf("String after encryptio: %s\n", encrypted);
        printf("Hex after encryptio: %s\n", hex_encrypted);

        // 解密
        char* decrypted = mcp_decrypt(encrypted,  key);
        if (decrypted) {
            printf("After decryption: %s\n", decrypted);
            printf("Length After decryption: %zu\n", strlen(decrypted));
            free(decrypted);
        }

        free(hex_encrypted);
        free(encrypted);
    }

    printf("=== Test is completed ===\n");
}

// 网络传输示例
void network_example() {
    const char* json_data = "{\"id\": \"300281\", \"version\": \"1.0\"}";
    const char* key = "mcp_protocol_2025";

    printf("\n=== 网络传输示例 ===\n");
    printf("原始数据: %s\n", json_data);

    // 加密
    int encrypted_len=0;
    char* encrypted = mcp_encrypt(json_data, key);
    if (encrypted) {
        char* hex_data = bytes_to_hex(encrypted, encrypted_len);
        printf("C端加密结果: %s\n", hex_data);

        // 这里可以发送 hex_data 给 Java 端

        free(hex_data);
        free(encrypted);
    }
}// 测试函数